const { Order, OrderItem, Product, User, PointsTransaction, sequelize } = require('../models')
const productService = require('./productService')
const pointsService = require('./pointsService')
const memberService = require('./memberService')
const logger = require('../utils/logger')
const { Op } = require('sequelize')

class OrderService {
  /**
   * 创建订单
   * @param {Object} orderData - 订单数据
   * @returns {Promise<Object>} 创建的订单
   */
  async createOrder(orderData) {
    const transaction = await sequelize.transaction()
    
    try {
      const {
        userId,
        type = 'offline',
        items,
        notes,
        discountRate = 0
      } = orderData

      // 验证用户
      const user = await User.findByPk(userId)
      if (!user) {
        throw new Error('用户不存在')
      }

      // 验证商品和计算总价
      let totalPoints = 0
      let originalPoints = 0
      let totalQuantity = 0
      const validatedItems = []

      for (const item of items) {
        const product = await Product.findByPk(item.productId)
        if (!product || product.status !== 1) {
          throw new Error(`商品不存在或已下架: ${item.productId}`)
        }

        // 检查库存
        if (product.stock_quantity < item.quantity) {
          throw new Error(`商品库存不足: ${product.name}`)
        }

        const itemTotal = parseFloat(product.points_price) * item.quantity
        originalPoints += itemTotal
        totalQuantity += item.quantity

        validatedItems.push({
          productId: product.id,
          productName: product.name,
          productType: product.type,
          unitPoints: product.points_price,
          quantity: item.quantity,
          totalPoints: itemTotal,
          printOptions: item.printOptions || null,
          fileId: item.fileId || null
        })
      }

      // 计算会员折扣
      const memberDiscount = await memberService.calculateOrderDiscount(userId, originalPoints)
      const memberDiscountPoints = memberDiscount.discountAmount
      
      // 应用额外折扣（如果有）
      const additionalDiscountPoints = originalPoints * discountRate
      
      // 总折扣 = 会员折扣 + 额外折扣
      const discountPoints = memberDiscountPoints + additionalDiscountPoints
      totalPoints = originalPoints - discountPoints

      // 检查用户积分余额
      if (user.points < totalPoints) {
        throw new Error('积分余额不足')
      }

      // 生成订单号和预约码
      const orderNo = this.generateOrderNo()
      const reservationCode = type === 'offline' ? this.generateReservationCode() : null

      // 创建订单
      const order = await Order.create({
        order_no: orderNo,
        user_id: userId,
        type,
        total_points: totalPoints,
        original_points: originalPoints,
        discount_points: discountPoints,
        total_quantity: totalQuantity,
        status: 'pending',
        reservation_code: reservationCode,
        notes
      }, { transaction })

      // 创建订单项
      const orderItems = validatedItems.map(item => ({
        ...item,
        order_id: order.id
      }))
      
      await OrderItem.bulkCreate(orderItems, { transaction })

      // 扣减库存
      for (const item of validatedItems) {
        await productService.updateStock(item.productId, -item.quantity)
      }

      // 扣减用户积分
      await pointsService.deductPoints(userId, totalPoints, {
        type: 'exchange',
        description: `商品兑换 - 订单${orderNo}`,
        relatedId: order.id
      })

      await transaction.commit()

      // 返回完整订单信息
      const createdOrder = await this.getOrderById(order.id)
      
      logger.info(`订单创建成功: ${orderNo}, 用户: ${userId}, 总积分: ${totalPoints}`)
      
      return createdOrder

    } catch (error) {
      await transaction.rollback()
      logger.error('创建订单失败:', error)
      throw error
    }
  }

  /**
   * 获取订单详情
   * @param {number} orderId - 订单ID
   * @returns {Promise<Object>} 订单详情
   */
  async getOrderById(orderId) {
    try {
      const order = await Order.findByPk(orderId, {
        include: [
          {
            model: User,
            as: 'User', // 修正别名
            attributes: ['id', 'phone', 'nickname']
          },
          {
            model: OrderItem,
            as: 'items',
            include: [
              {
                model: Product,
                as: 'product',
                attributes: ['id', 'name', 'image_url', 'category', 'type']
              }
            ]
          }
        ]
      })

      if (!order) {
        throw new Error('订单不存在')
      }

      return order
    } catch (error) {
      logger.error('获取订单详情失败:', error)
      throw error
    }
  }

  /**
   * 获取所有订单列表（管理员用）
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 订单列表和分页信息
   */
  async getAllOrders(options = {}) {
    try {
      const {
        status,
        type,
        userId,
        startDate,
        endDate,
        page = 1,
        limit = 20
      } = options

      const where = {}
      
      if (status) {
        where.status = status
      }
      
      if (type) {
        where.type = type
      }
      
      if (userId) {
        where.user_id = userId
      }
      
      if (startDate && endDate) {
        where.created_at = {
          [Op.between]: [startDate, endDate]
        }
      }

      const offset = (page - 1) * limit

      const result = await Order.findAndCountAll({
        where,
        include: [
          {
            model: User,
            as: 'User', // 修正别名
            attributes: ['id', 'phone', 'nickname']
          },
          {
            model: OrderItem,
            as: 'items',
            include: [
              {
                model: Product,
                as: 'product',
                attributes: ['id', 'name', 'image_url']
              }
            ]
          }
        ],
        limit: parseInt(limit),
        offset,
        order: [['created_at', 'DESC']]
      })

      return {
        orders: result.rows,
        pagination: {
          total: result.count,
          page: parseInt(page),
          limit: parseInt(limit),
          pages: Math.ceil(result.count / limit)
        }
      }
    } catch (error) {
      logger.error('获取所有订单列表失败:', error)
      throw new Error('获取订单列表失败')
    }
  }

  /**
   * 获取用户订单列表
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 订单列表和分页信息
   */
  async getUserOrders(options = {}) {
    try {
      const {
        userId,
        status,
        type,
        page = 1,
        limit = 20
      } = options

      const where = { user_id: userId }
      
      if (status) {
        where.status = status
      }
      
      if (type) {
        where.type = type
      }

      const offset = (page - 1) * limit

      const result = await Order.findAndCountAll({
        where,
        include: [
          {
            model: OrderItem,
            as: 'items',
            include: [
              {
                model: Product,
                as: 'product',
                attributes: ['id', 'name', 'image_url']
              }
            ]
          }
        ],
        limit: parseInt(limit),
        offset,
        order: [['created_at', 'DESC']]
      })

      return {
        orders: result.rows,
        pagination: {
          total: result.count,
          page: parseInt(page),
          limit: parseInt(limit),
          pages: Math.ceil(result.count / limit)
        }
      }
    } catch (error) {
      logger.error('获取用户订单列表失败:', error)
      throw new Error('获取订单列表失败')
    }
  }

  /**
   * 更新订单状态
   * @param {number} orderId - 订单ID
   * @param {string} status - 新状态
   * @param {Object} options - 更新选项
   * @returns {Promise<Object>} 更新后的订单
   */
  async updateOrderStatus(orderId, status, options = {}) {
    const transaction = await sequelize.transaction()
    
    try {
      const order = await Order.findByPk(orderId, { transaction })
      if (!order) {
        throw new Error('订单不存在')
      }

      const updateData = { status }
      
      if (status === 'completed') {
        updateData.completed_at = new Date()
        updateData.operator_id = options.operatorId
      } else if (status === 'cancelled') {
        updateData.cancelled_at = new Date()
        updateData.cancel_reason = options.cancelReason
        
        // 取消订单需要退还积分和库存
        await this.refundOrder(order, transaction)
      }

      await order.update(updateData, { transaction })
      await transaction.commit()

      logger.info(`订单状态更新: ${orderId}, 状态: ${status}`)
      
      return await this.getOrderById(orderId)

    } catch (error) {
      await transaction.rollback()
      logger.error('更新订单状态失败:', error)
      throw error
    }
  }

  /**
   * 取消订单并退还积分和库存
   * @param {Object} order - 订单对象
   * @param {Object} transaction - 数据库事务
   */
  async refundOrder(order, transaction) {
    try {
      // 只有pending状态的订单才能取消
      if (order.status !== 'pending') {
        throw new Error('只能取消待处理的订单')
      }

      // 退还积分
      await pointsService.addPoints(order.user_id, order.total_points, {
        type: 'refund',
        description: `订单取消退款 - 订单${order.order_no}`,
        relatedId: order.id
      })

      // 退还库存
      const orderItems = await OrderItem.findAll({
        where: { order_id: order.id },
        transaction
      })

      for (const item of orderItems) {
        await productService.updateStock(item.product_id, item.quantity)
      }

      logger.info(`订单退款完成: ${order.order_no}`)

    } catch (error) {
      logger.error('订单退款失败:', error)
      throw error
    }
  }

  /**
   * 根据预约码查找订单
   * @param {string} reservationCode - 预约码
   * @returns {Promise<Object>} 订单信息
   */
  async getOrderByReservationCode(reservationCode) {
    try {
      const order = await Order.findOne({
        where: { reservation_code: reservationCode },
        include: [
          {
            model: User,
            as: 'User', // 修正别名
            attributes: ['id', 'phone', 'nickname']
          },
          {
            model: OrderItem,
            as: 'items',
            include: [
              {
                model: Product,
                as: 'product'
              }
            ]
          }
        ]
      })

      if (!order) {
        throw new Error('预约码无效')
      }

      return order
    } catch (error) {
      logger.error('根据预约码查找订单失败:', error)
      throw error
    }
  }

  /**
   * 获取订单统计信息
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 统计信息
   */
  async getOrderStatistics(options = {}) {
    try {
      const { userId, startDate, endDate } = options
      
      const where = {}
      
      if (userId) {
        where.user_id = userId
      }
      
      if (startDate && endDate) {
        where.created_at = {
          [Op.between]: [startDate, endDate]
        }
      }

      const [totalOrders, completedOrders, cancelledOrders, totalPoints] = await Promise.all([
        Order.count({ where }),
        Order.count({ where: { ...where, status: 'completed' } }),
        Order.count({ where: { ...where, status: 'cancelled' } }),
        Order.sum('total_points', { where: { ...where, status: 'completed' } })
      ])

      return {
        totalOrders,
        completedOrders,
        cancelledOrders,
        pendingOrders: totalOrders - completedOrders - cancelledOrders,
        totalPoints: totalPoints || 0
      }
    } catch (error) {
      logger.error('获取订单统计失败:', error)
      throw new Error('获取订单统计失败')
    }
  }

  /**
   * 生成订单号
   * @returns {string} 订单号
   */
  generateOrderNo() {
    const timestamp = Date.now().toString()
    const random = Math.random().toString(36).substr(2, 6).toUpperCase()
    return `ORD${timestamp}${random}`
  }

  /**
   * 生成预约码
   * @returns {string} 预约码
   */
  generateReservationCode() {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    let result = ''
    for (let i = 0; i < 8; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length))
    }
    return result
  }

  /**
   * 验证订单可以兑换
   * @param {Object} orderData - 订单数据
   * @returns {Promise<Object>} 验证结果
   */
  async validateOrder(orderData) {
    try {
      const { userId, items } = orderData

      // 验证用户
      const user = await User.findByPk(userId)
      if (!user) {
        throw new Error('用户不存在')
      }

      // 验证商品和库存
      let totalPoints = 0
      const validationResults = []

      for (const item of items) {
        const product = await Product.findByPk(item.productId)
        if (!product || product.status !== 1) {
          validationResults.push({
            productId: item.productId,
            valid: false,
            error: '商品不存在或已下架'
          })
          continue
        }

        if (product.stock_quantity < item.quantity) {
          validationResults.push({
            productId: item.productId,
            valid: false,
            error: '库存不足',
            available: product.stock_quantity
          })
          continue
        }

        const itemTotal = parseFloat(product.points_price) * item.quantity
        totalPoints += itemTotal

        validationResults.push({
          productId: item.productId,
          valid: true,
          product: {
            id: product.id,
            name: product.name,
            points_price: product.points_price,
            stock_quantity: product.stock_quantity
          },
          quantity: item.quantity,
          totalPoints: itemTotal
        })
      }

      // 检查积分余额
      const hasEnoughPoints = user.points >= totalPoints

      return {
        valid: validationResults.every(r => r.valid) && hasEnoughPoints,
        totalPoints,
        userPoints: user.points,
        hasEnoughPoints,
        items: validationResults
      }

    } catch (error) {
      logger.error('验证订单失败:', error)
      throw error
    }
  }
}

module.exports = new OrderService()